#ifndef PLOT_REALTIME_H
#define PLOT_REALTIME_H

#define _USE_MATH_DEFINES
#include <stdio.h>  
#include <iostream>
#include <cmath>
#include <pthread.h>
#include <unistd.h>
#include <time.h>
#include "matplotlibcpp.h"

using namespace std;
namespace plt = matplotlibcpp;

class plot_realtime
{
public:	

    /**
     * @brief plot_realtime c++实时数据显示
     */
	plot_realtime();

    ~plot_realtime();

    /**
     * @brief plot 显示value变化曲线，需要手动存储数据到vector中，显示不会丢失数据
     * @param value 包含所有需要显示的double值的vector
     */
    void plot(vector<double>& value);

    /**
     * @brief plot 显示value变化曲线，不需要手动存储数据到vector中，显示可能丢失数据
     * @param value 需要显示的double
     */
    void plot(double& value);

    /**
     * @brief plot 显示value与time的关系曲线，需要手动存储数据到vector中，显示不会丢失数据
     * @param time 包含所有横坐标值的vector
     * @param value 包含所有纵坐标值的vector
     */
    void plot(vector<double>& time, vector<double>& value);

    /**
     * @brief double_plot 在同一张图上显示value1和value2的变化曲线，需要手动存储数据到vector中，显示不会丢失数据
     * @param value1 包含所有value1值的vector
     * @param value2 包含所有value2值的vector
     */
    void double_plot(vector<double>& value1, vector<double>& value2);

    /**
     * @brief double_plot 在同一张图上显示value1和value2的变化曲线，不需要手动存储数据到vector中，显示可能丢失数据
     * @param value1 需要显示的double value1
     * @param value2 需要显示的double value2
     */
    void double_plot(double& value1, double& value2);

    /**
     * @brief double_plot 在同一张图上显示value1和time1、value2和time2的关系曲线，需要手动存储数据到vector中，显示不会丢失数据
     * @param time1
     * @param value1
     * @param time2
     * @param value2
     */
	void double_plot(vector<double>& time1, vector<double>& value1, vector<double>& time2, vector<double>& value2);

    /**
     * @brief six_figure_double_plot 会有6个subplot，每个plot会显示两组值，不需要手动存储数据到vector中，显示大几率丢失数据，不建议使用
     * @param value1_1
     * @param value1_2
     * @param value2_1
     * @param value2_2
     * @param value3_1
     * @param value3_2
     * @param value4_1
     * @param value4_2
     * @param value5_1
     * @param value5_2
     * @param value6_1
     * @param value6_2
     */
    void six_figure_double_plot(double& value1_1, double& value1_2, double& value2_1, double& value2_2, double& value3_1, double& value3_2, double& value4_1, double& value4_2, double& value5_1, double& value5_2, double& value6_1, double& value6_2);

    /**
     * @brief six_figure_double_plot 会有6个subplot，每个plot会显示两组值，需要手动存储数据到vector中，显示不会丢失数据
     * @param value1_1
     * @param value1_2
     * @param value2_1
     * @param value2_2
     * @param value3_1
     * @param value3_2
     * @param value4_1
     * @param value4_2
     * @param value5_1
     * @param value5_2
     * @param value6_1
     * @param value6_2
     */
    void six_figure_double_plot(vector<double>& value1_1, vector<double>& value1_2, vector<double>& value2_1, vector<double>& value2_2, vector<double>& value3_1, vector<double>& value3_2, vector<double>& value4_1, vector<double>& value4_2, vector<double>& value5_1, vector<double>& value5_2, vector<double>& value6_1, vector<double>& value6_2);
	
    /**
     * @brief exit 停止画图并关闭窗口
     */
	void exit();
	
protected:
	//protected members here;
	//normally, most of variables and inside functions are here;

    vector<double> *x;
    vector<double> *y;
    vector<double> *x1;
    vector<double> *y1;
    double * x_value;
    double * y_value;
    double * x1_value;
    double * y1_value;
    vector<double> x_vector;
    vector<double> y_vector;
    vector<double> x1_vector;
    vector<double> y1_vector;

    vector<double> *x1_1;
    vector<double> *x1_2;
    vector<double> *x2_1;
    vector<double> *x2_2;
    vector<double> *x3_1;
    vector<double> *x3_2;
    vector<double> *x4_1;
    vector<double> *x4_2;
    vector<double> *x5_1;
    vector<double> *x5_2;
    vector<double> *x6_1;
    vector<double> *x6_2;

    double * x1_1_value;
    double * x1_2_value;
    double * x2_1_value;
    double * x2_2_value;
    double * x3_1_value;
    double * x3_2_value;
    double * x4_1_value;
    double * x4_2_value;
    double * x5_1_value;
    double * x5_2_value;
    double * x6_1_value;
    double * x6_2_value;

    vector<double> x1_1_vector;
    vector<double> x1_2_vector;
    vector<double> x2_1_vector;
    vector<double> x2_2_vector;
    vector<double> x3_1_vector;
    vector<double> x3_2_vector;
    vector<double> x4_1_vector;
    vector<double> x4_2_vector;
    vector<double> x5_1_vector;
    vector<double> x5_2_vector;
    vector<double> x6_1_vector;
    vector<double> x6_2_vector;

    pthread_t pth;
    bool bExit = false;

    static void * plot_loop_pth(void * arg);
    static void * plot_novector_loop_pth(void * arg);

    static void * plot_loop_pth_two_para(void * arg);

    static void * plot_loop_pth_two_plot(void * arg);
    static void * plot_novector_loop_pth_two_plot(void * arg);

    static void * plot_loop_pth_two_plot_two_para(void * arg);

    static void * plot_novector_loop_pth_six_figure_double_plot_single_data(void * arg);
    static void * plot_loop_pth_six_figure_double_plot_single_data(void * arg);

private:
	//private members here;
};

#endif
